﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Threading;
using System.Windows.Forms.DataVisualization.Charting;
using System.Runtime.InteropServices;

namespace Serial_data
{
    public partial class Form1 : Form
    {
        [StructLayout(LayoutKind.Explicit, Size = 4)]
        struct U                                                    //串口接收浮点数的联合体
        {
            [FieldOffset(0)]
            public byte b0;
            [FieldOffset(1)]
            public byte b1;
            [FieldOffset(2)]
            public byte b2;
            [FieldOffset(3)]
            public byte b3;

            [FieldOffset(0)]
            public float fdata;
        }

        U x1_data;
        U x2_data;
        U x3_data;
        U x4_data;
        U x5_data;
        U x6_data;

        public Form1()
        {
            InitializeComponent();
            serialPort1.Encoding = Encoding.GetEncoding("GB2312");                                  //串口接收编码
            System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;

            this.chart1.Series.Clear();
            this.chart2.Series.Clear();
            this.chart3.Series.Clear();                                                             
            this.chart4.Series.Clear();
            this.chart5.Series.Clear();
            this.chart6.Series.Clear();                                                          //清除初始化图例，否则会有两个图例

            chart1.Series.Add("CH1");
            chart1.Series["CH1"].Color = Color.Red;                                              //不设置时默认橘黄色曲线
            this.chart1.ChartAreas[0].AxisY.Minimum = -45;
            this.chart1.ChartAreas[0].AxisY.Maximum = 45;
            this.chart1.ChartAreas[0].AxisX.Minimum = 0;
            this.chart1.ChartAreas[0].AxisX.Maximum = 90;
            chart1.Series["CH1"].ChartType = SeriesChartType.Spline;                              //chart1,Anglex(右上角显示图例功能)

            chart2.Series.Add("CH2");
            chart2.Series["CH2"].Color = Color.BlueViolet;
            this.chart2.ChartAreas[0].AxisY.Minimum = -45;
            this.chart2.ChartAreas[0].AxisY.Maximum = 45;
            this.chart2.ChartAreas[0].AxisX.Minimum = 0;
            this.chart2.ChartAreas[0].AxisX.Maximum = 90;
            chart2.Series["CH2"].ChartType = SeriesChartType.Spline;                              //chart2,Angley,spline出来的是曲线

            chart3.Series.Add("CH3");
            chart3.Series["CH3"].Color = Color.YellowGreen;
            this.chart3.ChartAreas[0].AxisY.Minimum = -45;
            this.chart3.ChartAreas[0].AxisY.Maximum = 45;
            this.chart3.ChartAreas[0].AxisX.Minimum = 0;
            this.chart3.ChartAreas[0].AxisX.Maximum = 90;
            chart3.Series["CH3"].ChartType = SeriesChartType.Spline;                              //chart3,CH3

            chart4.Series.Add("CH4");
            chart4.Series["CH4"].Color = Color.Aqua;
            this.chart4.ChartAreas[0].AxisY.Minimum = -45;
            this.chart4.ChartAreas[0].AxisY.Maximum = 45;
            this.chart4.ChartAreas[0].AxisX.Minimum = 0;
            this.chart4.ChartAreas[0].AxisX.Maximum = 90;
            chart4.Series["CH4"].ChartType = SeriesChartType.Spline;                              //chart4,CH4

            chart5.Series.Add("CH5");
            chart5.Series["CH5"].Color = Color.Black;
            this.chart5.ChartAreas[0].AxisY.Minimum = -45;
            this.chart5.ChartAreas[0].AxisY.Maximum = 45;
            this.chart5.ChartAreas[0].AxisX.Minimum = 0;
            this.chart5.ChartAreas[0].AxisX.Maximum = 90;
            chart5.Series["CH5"].ChartType = SeriesChartType.Spline;                              //chart5,CH5

            chart6.Series.Add("CH6");
            chart6.Series["CH6"].Color = Color.Chartreuse;
            this.chart6.ChartAreas[0].AxisY.Minimum = -45;
            this.chart6.ChartAreas[0].AxisY.Maximum = 45;
            this.chart6.ChartAreas[0].AxisX.Minimum = 0;
            this.chart6.ChartAreas[0].AxisX.Maximum = 90;
            chart6.Series["CH6"].ChartType = SeriesChartType.Spline;                              //chart6,CH6

            //=======================================================================================//
            chart1.Series["CH1"].Points.AddXY(90, 0);
            chart2.Series["CH2"].Points.AddXY(90, 0);
            chart3.Series["CH3"].Points.AddXY(90, 0);                                            //设置初始网格线（纯粹为了美观）
            chart4.Series["CH4"].Points.AddXY(90, 0);
            chart5.Series["CH5"].Points.AddXY(90, 0);
            chart6.Series["CH6"].Points.AddXY(90, 0);                                            //设置初始网格线（纯粹为了美观）
        }

        void chart_display()
        {
            Draw();
        }
        delegate void my_delegate();                                                             //加入一个代理，图表刷新在主线程，所以加委托
        Queue<double> Q1 = new Queue<double>();

        public void Draw()
        {
            if (!chart1.InvokeRequired)
            {
                this.chart1.Series["CH1"].Points.Clear();
                this.chart2.Series["CH2"].Points.Clear();
                this.chart3.Series["CH3"].Points.Clear();                                        //清除历史曲线记录，否则会凌乱
                this.chart4.Series["CH4"].Points.Clear();
                this.chart5.Series["CH5"].Points.Clear();
                this.chart6.Series["CH6"].Points.Clear();                                        //清除历史曲线记录，否则会凌乱

                for (int i = 0; i < FFF_chart1.Length; i++)
                {
                    chart1.Series["CH1"].Points.AddXY(i, FFF_chart1[i]);
                }

                for (int i = 0; i < FFF_chart2.Length; i++)
                {
                    chart2.Series["CH2"].Points.AddXY(i, FFF_chart2[i]);
                }

                for (int i = 0; i < FFF_chart3.Length; i++)
                {
                    chart3.Series["CH3"].Points.AddXY(i, FFF_chart3[i]);
                }
                for (int i = 0; i < FFF_chart4.Length; i++)
                {
                    chart4.Series["CH4"].Points.AddXY(i, FFF_chart4[i]);
                }
                for (int i = 0; i < FFF_chart5.Length; i++)
                {
                    chart5.Series["CH5"].Points.AddXY(i, FFF_chart5[i]);
                }
                for (int i = 0; i < FFF_chart6.Length; i++)
                {
                    chart6.Series["CH6"].Points.AddXY(i, FFF_chart6[i]);
                }
            }
            else
            {
                my_delegate delegate_FFF = new my_delegate(Draw);
                Invoke(delegate_FFF, new object[] { });
            }
        }

        public static class common                                                                  //定义全局变量的类
        {
            public static int icount = 0;                                                           //双列接收模式每行数据个数标志    
            public static Boolean flag = false;                                                     //双列接收模式空格标志
        }
        private void button3_Click_1(object sender, EventArgs e)
        {
            try
            {
                serialPort1.Close();                                                                //关闭串口        
                button2.Enabled = true;
                button3.Enabled = false;
            }
            catch
            {

            }
        }
        private void button4_Click(object sender, EventArgs e)
        {
            byte[] Data = new byte[1];                                                                      //单字节发数据     
            if (serialPort1.IsOpen)
            {
                try                                                                                         //防止输入字符串中含有非法字符（字母，汉字，符号等等，try，catch块可以捕捉并提示）
                {
                    for (int i = 0; i < (textBox2.Text.Length - textBox2.Text.Length % 2) / 2; i++)         //转换偶数个
                    {
                        Data[0] = Convert.ToByte(textBox2.Text.Substring(i * 2, 2), 16);                    //转换
                        serialPort1.Write(Data, 0, 1);
                    }
                    if (textBox2.Text.Length % 2 != 0)
                    {
                        Data[0] = Convert.ToByte(textBox2.Text.Substring(textBox2.Text.Length - 1, 1), 16); //单独处理最后一个字符
                        serialPort1.Write(Data, 0, 1);                                                      //写入
                    }
                }
                catch
                {
                    MessageBox.Show("数据转换错误，请输入数字。", "错误");
                }  
            }
        }

        private void serialPort1_DataReceived_1(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {                                                                                                           //用于显示两列数据的计数变量
            Thread chart_display_th = new Thread(new ThreadStart(chart_display));
            chart_display_th.Start();
            try
            {
                byte[] data = new byte[serialPort1.BytesToRead];                                                    //定义缓冲区，因为串口事件触发时有可能收到不止一个字节
                serialPort1.Read(data, 0, data.Length);
                if (data.Length >= 28 && data[0] == 85 && data[1] == 85 && data[26] == 170 && data[27] == 170)      //0x55 + 0x55 + 24个byte + 0xAA + 0xAA
                {
                    for(int count =0;count < 89; count++)                                                           //绘图队列，数据不超过90个
                    {
                        FFF_chart1[count] = FFF_chart1[count + 1];
                        FFF_chart2[count] = FFF_chart2[count + 1];
                        FFF_chart3[count] = FFF_chart3[count + 1];
                        FFF_chart4[count] = FFF_chart4[count + 1];
                        FFF_chart5[count] = FFF_chart5[count + 1];
                        FFF_chart6[count] = FFF_chart6[count + 1];
                    }
                    x1_data.b0 = data[2];
                    x1_data.b1 = data[3];
                    x1_data.b2 = data[4];
                    x1_data.b3 = data[5];

                    x2_data.b0 = data[6];
                    x2_data.b1 = data[7];
                    x2_data.b2 = data[8];
                    x2_data.b3 = data[9];

                    x3_data.b0 = data[10];
                    x3_data.b1 = data[11];
                    x3_data.b2 = data[12];
                    x3_data.b3 = data[13];

                    x4_data.b0 = data[14];
                    x4_data.b1 = data[15];
                    x4_data.b2 = data[16];
                    x4_data.b3 = data[17];

                    x5_data.b0 = data[18];
                    x5_data.b1 = data[19];
                    x5_data.b2 = data[20];
                    x5_data.b3 = data[21];

                    x6_data.b0 = data[22];
                    x6_data.b1 = data[23];
                    x6_data.b2 = data[24];
                    x6_data.b3 = data[25];

                    FFF_chart1[89] = x1_data.fdata;                                               //CH1数值刷新
                    FFF_chart2[89] = x2_data.fdata;                                               //CH2数值刷新
                    FFF_chart3[89] = x3_data.fdata;                                               //CH3数值刷新
                    FFF_chart4[89] = x4_data.fdata;                                               //CH4数值刷新
                    FFF_chart5[89] = x5_data.fdata;                                               //CH5数值刷新
                    FFF_chart6[89] = x6_data.fdata;                                               //CH6数值刷新

                    // 通道标签—数据刷新
                    label8.Text  = (x1_data.fdata).ToString();
                    label9.Text  = (x2_data.fdata).ToString();
                    label10.Text = (x3_data.fdata).ToString();
                    label11.Text = (x4_data.fdata).ToString();
                    label12.Text = (x5_data.fdata).ToString();
                    label13.Text = (x6_data.fdata).ToString();
                } 
            }
            catch { }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            comboBox1.Text = "COM2";                                                              //默认选项
            comboBox2.Text = "9600";
            FFF_chart1 = new double[90];
            FFF_chart2 = new double[90];
            FFF_chart3 = new double[90];
            FFF_chart4 = new double[90];
            FFF_chart5 = new double[90];
            FFF_chart6 = new double[90];
        }
        public double[] FFF_chart1;                                                               //对应CH1数据
        public double[] FFF_chart2;                                                               //对应CH2数据
        public double[] FFF_chart3;                                                               //对应CH3数据
        public double[] FFF_chart4;                                                               //对应CH4数据
        public double[] FFF_chart5;                                                               //对应CH5数据
        public double[] FFF_chart6;                                                               //对应CH6数据
        private void button2_Click_1(object sender, EventArgs e)
        {
            try
            {
                serialPort1.PortName = comboBox1.Text;                                              //端口号
                serialPort1.BaudRate = Convert.ToInt32(comboBox2.Text);                             //波特率
                serialPort1.Open();                                                                 //打开串口
                button2.Enabled = false;
                button3.Enabled = true;
            }
            catch
            {
                MessageBox.Show("打开端口失败，请检查！", "错误");
            }
        }
    }
}
